package com.mbl.base.core.utils;

import com.alibaba.fastjson.JSONArray;
import com.mbl.base.core.common.constant.MblConstantFactory;
import com.mbl.base.modular.config.entity.Dict;
import io.swagger.annotations.ApiModelProperty;
import jodd.util.StringUtil;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;
import java.util.stream.Collectors;

public class UtilClass {


    /**
     * 获取泛型参数类型Class
     * @param obj
     * @return
     */
    public static Class getClassByThis(Object obj){
        return getClassByThis(obj, 0);
    }
    public static Class getClassByThis(Object obj,int num){
        Class clz = obj.getClass();
        Type type = clz.getGenericSuperclass();//获取泛型父类，必须用该方法，此处的泛型父类不是指当前的类，而是具体继承的BaseAction<Standard>，当前类为BaseAction<T>泛型尚未确定
        ParameterizedType pt = (ParameterizedType) type;//将泛型父类转换为具体的那种类型
        Class modelClass = (Class) pt.getActualTypeArguments()[num];
        return modelClass;
    }

    /**
     * 获取对象属性列表
     * @param obj
     * @return
     */
    public static List<TypeAttribute> getAttributes(Object obj){
        final Class classByThis = getClassByThis(obj);
        final Field[] fields = classByThis.getDeclaredFields();
        final ArrayList<TypeAttribute> typeAttributes = new ArrayList<>();
        for (Field field : fields) {
            final TypeAttribute typeAttribute = new TypeAttribute();
            typeAttribute.setName(field.getName());
            typeAttribute.setType(getTypeInt(field));
            typeAttribute.setDictList(dictHandle(field.getName()));
            final boolean annotationPresent = field.isAnnotationPresent(ApiModelProperty.class);
            if (annotationPresent){
                final String value = field.getAnnotation(ApiModelProperty.class).value();
                typeAttribute.setText(value);
            }
            typeAttributes.add(typeAttribute);
        }
        return typeAttributes;
    }


    /**
     * 字典加工类
     * @param name
     * @return
     */
    private static List<Map<String, Object>> dictHandle(String name){
        if(StringUtils.isBlank(name) || !StringUtils.startsWith(name, "dict")){
            return null;
        }
        String dict = StringUtils.substringAfter(name, "dict");
        final List<Dict> dictList = MblConstantFactory.me().getDictListByCode(dict);
        final List<Map<String, Object>> collect = dictList.stream().map((Dict dict1) -> {
            Map<String, Object> map = new HashMap();
            map.put("name", dict1.getName());
            map.put("val", dict1.getVal());
            map.put("id",dict1.getId());
            return map;
        }).collect(Collectors.toList());
        return collect;
    }

    /**
     * 实例类型对象
     */
    @Data
    public static class TypeAttribute {
        /**
         * 属性名
         */
        private String name;
        /**
         * 属性类型
         * 1.String 11.文本域 12.富文本 13.图片(只保存url) 16:图片类型 17.图片列表（逗号隔开）
         * 2.Number 21.状态（1：启用，0：禁用）
         * 3:Date
         */
        private int type;
        /**
         * 字典列表
         */
        private List<Map<String,Object>> dictList;
        /**
         * 中文名称
         */
        private String text;
    }

    /**
     * 数字类型声明
     */
    private static List<Class> numberTypeList = new ArrayList(){{
        add(int.class);
        add(Integer.class);
        add(long.class);
        add(Long.class);
    }};
    /**
     * 时间类型声明
     */
    private static List<Class> dateTypeList = new ArrayList(){{
        add(Date.class);
        add(LocalDateTime.class);
        add(LocalDate.class);
        add(LocalTime.class);
    }};

    /**
     * 获取类型对应值
     * @param field
     * @return
     */
    private static int getTypeInt(Field field){
        final Class<?> type = field.getType();
        if(type == String.class){
            if(StringUtils.startsWith(field.getName(), "area")){
                return 11;
            }
            if(StringUtils.startsWith(field.getName(), "rich")){
                return 12;
            }
            if(StringUtils.startsWith(field.getName(), "img")){ // 非数组形式的图片
                return 13;
            }
            return 1;
        }
        if(type == JSONArray.class){
            if(StringUtils.startsWith(field.getName(), "images")){
                return 17;
            }
            if(StringUtils.startsWith(field.getName(), "image")){
                return 16;
            }
        }
        if(numberTypeList.contains(type)){
            return 2;
        }
        if(dateTypeList.contains(type)){
            return 3;
        }
        if(Boolean.class == type){
            if("status".equals(field.getName())){
                return 21;
            }
        }
        // 类型判断失败，返回1（默认字符串）
        return 1;
    }


    /**
     * 生成泛型实例对象
     * try {
     *             return (T) modelClass.getConstructor().newInstance();
     *         } catch (InstantiationException e) {
     *             e.printStackTrace();
     *         } catch (IllegalAccessException e) {
     *             e.printStackTrace();
     *         } catch (InvocationTargetException e) {
     *             e.printStackTrace();
     *         } catch (NoSuchMethodException e) {
     *             e.printStackTrace();
     *         }
     *         return null;
     */
}
